#include "ulib.h"
#include "sysenv.h"
#include "syscall.h"

static void
process_container(process_func_t func, void *data)
{
	 func(data);
	 /* TODO user resource clean up */
	 /* Then call the system to free the kernel resource */
	 sc_kprintf("proc %d ends\n", cur_pid());
	 sc_exit(0);
}

int
process_create_wait(process_func_t func, void *data, uint32_t stack_size)
{
	 /* Find the address for user stack */
	 char *stack_top = (char *)bmalloc(stack_size), *cur;
	 if (stack_top == 0) return -E_NO_MEM;
	 char *stack = PAGE_ALIGN(stack_top + stack_size - 1) + PAGE_SIZE;

	 stack -= sizeof(void *);
	 *(void **)stack = data;
	 stack -= sizeof(process_func_t);
	 *(process_func_t *)stack = func;
	 /* The fake return address */
	 stack -= sizeof(void *);
	 *(void **)stack = NULL;
	 
	 int pid = sc_proc_fork(cur_pid(), process_container, stack);
	 if (pid < 0)
	 {
		  /* TODO clean up */
	 }
	 return pid;
}

int
process_create(process_func_t func, void *data, uint32_t stack_size)
{
	 int result = process_create_wait(func, data, stack_size);
	 if (result > 0)
	 {
		  sc_notify_ex(result, WLEVEL_SYSTEM);
	 }
}
